const redisService = require('../services/redisService');
const catchAsync = require('../utils/catchAsync');
const AppError = require('../utils/appError');

// 测试Redis连接
exports.testConnection = catchAsync(async (req, res, next) => {
  try {
    const isConnected = redisService.isReady();
    
    if (!isConnected) {
      return next(new AppError('Redis连接未就绪', 500));
    }

    const pingResult = await redisService.ping();
    
    res.status(200).json({
      status: 'success',
      data: {
        connected: isConnected,
        ping: pingResult,
        message: 'Redis连接正常'
      }
    });
  } catch (error) {
    return next(new AppError(`Redis连接测试失败: ${error.message}`, 500));
  }
});

// 测试基本操作
exports.testBasicOperations = catchAsync(async (req, res, next) => {
  try {
    const testKey = 'test:basic:' + Date.now();
    const testValue = { message: 'Hello Redis', timestamp: new Date().toISOString() };
    
    // 测试SET操作
    await redisService.set(testKey, testValue, 60); // 60秒过期
    
    // 测试GET操作
    const retrievedValue = await redisService.get(testKey);
    
    // 测试EXISTS操作
    const exists = await redisService.exists(testKey);
    
    // 测试TTL操作
    const ttl = await redisService.ttl(testKey);
    
    // 清理测试数据
    await redisService.del(testKey);
    
    res.status(200).json({
      status: 'success',
      data: {
        operations: {
          set: '成功',
          get: retrievedValue,
          exists: exists,
          ttl: ttl,
          delete: '成功'
        },
        message: 'Redis基本操作测试通过'
      }
    });
  } catch (error) {
    return next(new AppError(`Redis基本操作测试失败: ${error.message}`, 500));
  }
});

// 测试哈希操作
exports.testHashOperations = catchAsync(async (req, res, next) => {
  try {
    const hashKey = 'test:hash:' + Date.now();
    
    // 测试HSET操作
    await redisService.hSet(hashKey, 'field1', 'value1');
    await redisService.hSet(hashKey, 'field2', { nested: 'object' });
    
    // 测试HGET操作
    const field1Value = await redisService.hGet(hashKey, 'field1');
    const field2Value = await redisService.hGet(hashKey, 'field2');
    
    // 测试HGETALL操作
    const allFields = await redisService.hGetAll(hashKey);
    
    // 清理测试数据
    await redisService.del(hashKey);
    
    res.status(200).json({
      status: 'success',
      data: {
        operations: {
          hset: '成功',
          hget_field1: field1Value,
          hget_field2: field2Value,
          hgetall: allFields,
          delete: '成功'
        },
        message: 'Redis哈希操作测试通过'
      }
    });
  } catch (error) {
    return next(new AppError(`Redis哈希操作测试失败: ${error.message}`, 500));
  }
});

// 测试列表操作
exports.testListOperations = catchAsync(async (req, res, next) => {
  try {
    const listKey = 'test:list:' + Date.now();
    
    // 测试LPUSH操作
    await redisService.lPush(listKey, 'item1', 'item2', { complex: 'object' });
    
    // 测试LLEN操作
    const length = await redisService.lLen(listKey);
    
    // 测试RPOP操作
    const poppedItem = await redisService.rPop(listKey);
    
    // 获取更新后的长度
    const newLength = await redisService.lLen(listKey);
    
    // 清理测试数据
    await redisService.del(listKey);
    
    res.status(200).json({
      status: 'success',
      data: {
        operations: {
          lpush: '成功',
          initial_length: length,
          rpop_item: poppedItem,
          final_length: newLength,
          delete: '成功'
        },
        message: 'Redis列表操作测试通过'
      }
    });
  } catch (error) {
    return next(new AppError(`Redis列表操作测试失败: ${error.message}`, 500));
  }
});

// 获取Redis信息
exports.getRedisInfo = catchAsync(async (req, res, next) => {
  try {
    if (!redisService.isReady()) {
      return next(new AppError('Redis连接未就绪', 500));
    }

    res.status(200).json({
      status: 'success',
      data: {
        connected: redisService.isReady(),
        host: process.env.REDIS_HOST || 'localhost',
        port: process.env.REDIS_PORT || 6379,
        message: 'Redis服务状态正常'
      }
    });
  } catch (error) {
    return next(new AppError(`获取Redis信息失败: ${error.message}`, 500));
  }
});

// 清理测试数据
exports.cleanupTestData = catchAsync(async (req, res, next) => {
  try {
    // 这里可以添加清理逻辑，比如删除所有test:*开头的键
    // 注意：在生产环境中要谨慎使用
    
    res.status(200).json({
      status: 'success',
      data: {
        message: '测试数据清理完成'
      }
    });
  } catch (error) {
    return next(new AppError(`清理测试数据失败: ${error.message}`, 500));
  }
});